# 基础语法
# 简介
JavaScript 是一种轻量级的脚本语言。脚本语言指的是它不具备开发操作系统的能力,而是只用来编写控制其他大型应用程序(比如浏览器)的“脚本”。
JavaScript 也是一种嵌入式(embedded)语言。它提供的核心语法不算很多,只能用来做一些数学和逻辑运算。JavaScript 本身不提供任何与 I/O(输入/输出)相关的 API,都要靠宿主环境(host)提供,所以它只合适嵌入更大型的应用程序环境,去调用宿主环境提供的底层 API。目前,已经嵌入 JavaScript 的宿主环境有:浏览器,Node 服务器环境。
从语法角度看,JavaScript 语言是一种“对象模型”语言,还支持函数式编程。
JavaScript 的核心语法部分相当精简,只包括两个部分:
- 基本的语法构造(比如操作符、控制结构、语句)
- 标准库(就是一系列具有各种功能的对象比如
Array、Date、Math等)
各种宿主环境提供额外的 API(即只能在该环境使用的接口),以便 JavaScript 调用。
浏览器提供的额外 API 可以分成三大类:
- 浏览器控制类:操作浏览器
- DOM 类:操作网页的各种元素
- Web 类:实现互联网的各种功能
Node 环境会提供操作系统的 API,比如文件操作 API、网络通信 API等等
组成:ECMAScript + BOM + DOM
# 与 HTML 组合
内部引入
<script> js代码; </script>在HTML标签中写入
<img src="img/1.jpg" id="img1" onclick="javascript:fun2();">外部引入
<script src="js/a.js"></script> <!-- type="text/javascript"可省略 --> <script src="js/b.js"></script>
TIP
head 中定义的 JavaScript 将会在页面加载前执行,会阻塞页面加载,除非该JS需在网页全部加载完成前就可以调用,否则推荐定义在 </body> 闭合标签之前
Chrome进入 Console 途径:
- Mac:
Command + option + j;Win:Ctrl + Shift + j - Mac:
Command + option + i;Win:Ctrl + Shift + i再选择 Console 面板
# 数据类型
# 定义
undefined(未定义):若变量未初始化则默认值为undefined或直接赋值undefinednumber(数值):不区分整数和小数、NaN(not a number)。所有数字都是以64位浮点数形式储存;位运算只有整数才能完成,此时 JavaScript 会自动转成32位整数,然后运算
string(字符串):单引和双引都可以boolean(布尔):true和falsenull(空):即此处的值为空。一个对象为空的占位符或直接赋值nulltypeof null返回Object,JS最初的错误被ECMAScript沿用。现在 null 被认为是对象的占位符,从而解释了该矛盾object(对象):各种值组成的集合,可以分成三个子类型object(狭义的对象)array(数组)function(函数)
TIP
ES5 只有 6 种,ES6 即 ECMAScript 2015 添加了一种Symbol
通常number、string、boolean这三种类型,合称为原始类型(primitive type)的值,即它们是最基本的数据类型,不能再细分了。对象则称为合成类型(complex type)的值,因为一个对象往往是多个原始类型的值的合成,可以看作是一个存放各种值的容器。
注意小数的计算精度
console.log(0.1 + 0.2 === 0.3); // false
console.log(0.3 / 0.1); // 2.9999999999999996
console.log(0.3 - 0.2 === 0.2 - 0.1); // false
# 判断值的类型
JavaScript 有三种方法,可以确定一个值到底是什么类型。
typeof运算符console.log(typeof undefiend); // undefiend,用来检查一个没有声明的变量,而不报错。 console.log(typeof 123); // number console.log(typeof "123"); // string console.log(typeof false); // boolean console.log(typeof null); // object console.log(typeof {}); // object console.log(typeof [1]); // object console.log(typeof function name(params) {}); // functioninstanceof运算符,面向对象使用Object.prototype.toString方法
# 变量
弱类型,区分大小写,但是变量一般都用小写字母开头的驼峰表示法表示
全局变量:在script标签里面定义一个变量,这个变量在页面中js部分都可以使用
- 在任何方法之外放置的var语句;
var foo = value; - 给全局对象添加一个属性:
windows.foo = value; - 直接使用未经声明的变量(隐式全局变量):
foo = value;,不建议使用
局部变量:ES6之前在函数内部定义一个变量,只能在方法内部使用:var foo = value;,其他查看作用域和闭包章节。
声明的提升:详细查看“作用域和闭包中声明的提升章节”,
//原本语句如下:
console.log(a); //不会报错,会输出undefined
var a = 1;
//真正运行的代码如下:
var a;
console.log(a); //会输出undefined,表示a已经声明,但为赋值
a = 1;
# 常量
ES6添加。使用const定义,采取全大写并用下划线分割。值不可改变!
# 运算符
# 赋值运算符
=、+=、-=
# 一元运算符
++(自增)、--(自减)、+(正号,二元运算时可做拼接字符串)、-(负号)
注意:在JS中,一元运算符如果运算数不是运算符所要求的类型,那么js引擎会自动的将运算数进行类型转换。
string转number:按照字面值转换。如果字面值不是数字,则转为NaN(不是数字的数字)boolean转number:true转为1,false转为0
# 三元运算符
表达式? 值1:值2;
# 算术运算符
+、-、*、/、%(取余,余数趋于0)、**(指数操作,如2^2=4)
# 比较运算符
>、<、>=、<=、==、===(全等于),比较方式如下:
- 类型相同:直接比较
- 字符串:按照字典顺序(ASCII)比较。按位逐一比较,直到得出大小为止。
- 类型不同:先进行类型转换,再比较
==:比较的只是值(会执行类型转换)===:全等于。在比较之前,先判断类型,如果类型不一样,则直接返回false
console.log(undefined == null); // true
console.log(undefined === null); // false
# 逻辑运算符
&&、||、!
JS 中代表 false的值有(对应数据类型即可记忆):undefined, NaN, 0, "", false, null
其他类型转boolean
number:0或NaN为假,其他为真string:除了空字符串(""),其他都是true。注意空格占位的不是空字符串null&undefined:都是false- 对象:所有对象都为
true。判断空指针异常(若是字符串都不用判断长度)时直接写if(obj)
console.log(true && "hello");// hello
console.log(false || "default"); // default,可用于默认值
console.log(1 + 2 || "default"); // 3
console.log(!4); // false
console.log(!!4); // true
# 位运算符
&、|、~、^,转为32位二进制补码进行计算
console.log(5 & 3); //1
console.log(5 | 3); //7
console.log(~5); // -6
console.log(5 ^ 3); //6
# 位移运算符
位移运算符:不改变原变量数值。输入输出都是对整数类型的二进制补码进行的运算!如下解释以及画图时也应用补码来解释!
<<左移,被移除的高位丢弃,低位空缺位补0。当顶替掉符号位时数值正负改变。>>右移,被移位的二进制最高位是0,右移后所有空缺位补0;最高位是1,所有空缺位补1。>>>无符号右移,使用“零扩展”(zero extension),即被移位二进制最高位无论是0或者是1,空缺位都用0补。C/C++ 没有
# 流程控制
- if...else...(同Java)
- while...、do...while...(同Java)
- switch case default
- Java中
switch可以接收的数据类型:byte、short、char、int、Enum(1.5) 、String(1.7) - JavaScript中
switch可以接收任意的原始数据类型 - 都有 break 关键字
- Java中
- for:var定义的变量不是局部变量,无论布尔表达式是否满足,步进表达式都会执行。所以可以用let来来限制作用范围。
for...in:遍历数组或者对象的属性:for (变量 in 对象)for...of:遍历iterable类型,如Array、Map和Set的值,for (变量 of 对象)
- 跳出循环:(
break、continue只针对最内层循环)break语句用于跳出代码块或循环continue语句用于立即终止本轮循环,返回循环结构的头部,开始下一轮循环label标签通常与break语句和continue语句配合使用,跳出特定的循环return虽然也可以跳出,但是通常用来返回方法
# Other(未整理好)
# 基本类型的包装对象
String
- 创建对象
var str = "abc"; - 属性:
length,字符串长度 - 方法:
- 与html相关的方法
bold():加粗fontcolor(): 设置字符串的颜色fontsize(): 设置字体的大小link(): 将字符串显示成超链接str4.link("hello.html")sub()sup(): 下标和上标
- 与Java相似的方法
concat(): 连接字符串charAt():返回指定指定位置的字符串,若字符位置不存在,返回空字符串indexOf():返回字符串位置split():切分字符串,成数组replace():替换字符串,传递两个参数:原始字符、要替换成的字符substr():从第几位开始,向后截取几位substring():[从第几位开始,到第几位结束)
- 创建对象
Boolean:
var flag = new Boolean(true);,不传值时默认为false
# Global
特点:全局对象,这个Global中封装的方法不需要对象就可以
方法名();直接调用。方法:
encodeURI():对字符进行url编码,返回另一个字符。不编码字符有82个decodeURI():对字符进行url解码,返回另一个字符encodeURIComponent():对字符进行url编码,编码的字符更多。不编码字符有71个decodeURIComponent():对字符进行url解码传智播客 = %E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2parseInt():将字符串转为数字;进制转换 * 逐一判断每一个字符是否是数字,直到不是数字为止,将前边数字部分转为number,第一个也不是数字则为NaN *parseInt('11',2),返回3isNaN():判断一个值是否是NaN - NaN六亲不认,连自己都不认。NaN参与的==比较全部返回falseeval():==将JavaScript字符串,作为脚本代码来执行==,若字符串不是脚本代码则不执行var str = "alert('1234');"; alert(str); //alert('1234'); eval(str); //1234
# Base64
使用场景
- 文本里面包含一些不可打印的符号,比如 ASCII 码0到31的符号,可以使用 Base64 编码转成可以打印的字符。
- 需要以文本格式传递二进制数据,那么也可以使用 Base64 编码。
所谓 Base64 就是一种编码方法,可以将任意值转成 0~9、A~Z、a-z、+和/这64个字符组成的可打印字符。使用它的主要目的,不是为了加密,而是为了不出现特殊字符,简化程序的处理。JS提供了如下全局函数
btoa():任意值转为 Base64 编码atob():Base64 编码转为原来的值
var str = "hello world";
console.log(btoa(str)); // aGVsbG8gd29ybGQ
console.log(atob("aGVsbG8gd29ybGQ")); // hello world
注意,这两个方法不适合非 ASCII 码的字符,如中文字符,会报错。要将非 ASCII 码字符转为 Base64 编码,必须中间插入一个URL转码环节,JS提供如下全局函数,再使用这两个方法
function b64Encode(str) {
return btoa(encodeURIComponent(str));
}
function b64Decode(str) {
return decodeURIComponent(atob(str));
}
console.log(b64Encode("你好")); // "JUU0JUJEJUEwJUU1JUE1JUJE"
console.log(b64Decode("JUU0JUJEJUEwJUU1JUE1JUJE")); // "你好"